package com.bingxue.edu.management.listener;

import cn.hutool.core.util.StrUtil;
import com.bingxue.edu.common.config.NotifyConfigProperties;
import com.bingxue.edu.common.config.WechatProperties;
import com.bingxue.edu.management.education.model.entity.ClassInfo;
import com.bingxue.edu.management.education.model.entity.EnrollChangeRecord;
import com.bingxue.edu.management.education.model.entity.Student;
import com.bingxue.edu.management.education.service.ClassInfoService;
import com.bingxue.edu.management.education.service.EnrollChangeRecordService;
import com.bingxue.edu.management.education.service.StudentService;
import com.bingxue.edu.management.event.LessonChangedEvent;
import com.bingxue.edu.management.system.model.entity.Employee;
import com.bingxue.edu.management.system.service.EmployeeService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.bean.message.WxCpMessage;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionalEventListener;

import java.util.LinkedHashMap;
import java.util.LinkedList;

import static com.bingxue.edu.common.constant.DateConstants.FORMATTER_TIME_HHmm_CN;

/**
 * @author panbo
 * @since 2024/11/12
 */
@Slf4j
@RequiredArgsConstructor
@Component
public class LessonChangedEventListener {

    private final WechatProperties wechatProperties;
    private final NotifyConfigProperties notifyConfigProperties;
    private final WxCpService wxCpService;

    private final EmployeeService employeeService;
    private final ClassInfoService classInfoService;
    private final StudentService studentService;
    private final EnrollChangeRecordService enrollChangeRecordService;

    @Async
    @TransactionalEventListener(fallbackExecution = true)
    public void onEventListen(LessonChangedEvent event) {
        EnrollChangeRecord record = enrollChangeRecordService.getById(event.getChangeRecordId());
        sendNotify(record);
    }

    private void sendNotify(EnrollChangeRecord record) {
        NotifyConfigProperties.SceneConfig config = notifyConfigProperties.getLessonChangedTip();
        if (!config.isTeacherWecomEnabled()) {
            return;
        }
        try {
            Student student = studentService.getById(record.getStudentId());
            String originalClassId = record.getOriginalClassId();
            String targetClassId = record.getTargetClassId();
            ClassInfo originalClass = classInfoService.getById(originalClassId);
            ClassInfo targetClass = classInfoService.getById(targetClassId);
            String originalClassName = originalClass.getName();
            String targetClassName = targetClass.getName();

            LinkedList<String> originalClassUserCodeList = new LinkedList<>();
            if (StrUtil.isNotEmpty(originalClass.getLeadTeacherId())) {
                Employee leadTeacher = employeeService.getById(originalClass.getLeadTeacherId());
                originalClassName = "【%s】".formatted(leadTeacher.getName()) + originalClassName;
                originalClassUserCodeList.push(leadTeacher.getCode());
            }
            if (StrUtil.isNotEmpty(originalClass.getAssistTeacherId())) {
                Employee assistTeacher = employeeService.getById(originalClass.getAssistTeacherId());
                originalClassUserCodeList.push(assistTeacher.getCode());
            }

            LinkedList<String> targetClassUserCodeList = new LinkedList<>();
            if (StrUtil.isNotEmpty(targetClass.getLeadTeacherId())) {
                Employee leadTeacher = employeeService.getById(targetClass.getLeadTeacherId());
                targetClassName = "【%s】".formatted(leadTeacher.getName()) + targetClassName;
                targetClassUserCodeList.push(leadTeacher.getCode());
            }
            if (StrUtil.isNotEmpty(targetClass.getAssistTeacherId())) {
                Employee assistTeacher = employeeService.getById(targetClass.getAssistTeacherId());
                targetClassUserCodeList.push(assistTeacher.getCode());
            }


            if (!originalClassUserCodeList.isEmpty()) {
                String toUser = String.join("|", originalClassUserCodeList);
                WxCpMessage wxCpMessage = buildWxCpMessage(student, record, originalClassName, targetClassName);
                wxCpMessage.setToUser(toUser);
                wxCpMessage.setPage(String.format("pages/class/detail?id=%s", originalClassId));
                wxCpMessage.setTitle("学生调出通知");
                wxCpService.getMessageService().send(wxCpMessage);
            }

            if (!targetClassUserCodeList.isEmpty()) {
                String toUser = String.join("|", targetClassUserCodeList);
                WxCpMessage wxCpMessage = buildWxCpMessage(student, record, originalClassName, targetClassName);
                wxCpMessage.setToUser(toUser);
                wxCpMessage.setPage(String.format("pages/class/detail?id=%s", targetClassId));
                wxCpMessage.setTitle("学生调入通知");
                wxCpService.getMessageService().send(wxCpMessage);
            }
            log.error("发送企业微信通知成功：调课通知");
        } catch (Exception e) {
            log.error("发送企业微信通知失败, {}", e.getMessage(), e);
        }
    }

    private WxCpMessage buildWxCpMessage(Student student, EnrollChangeRecord record, String originalClassName, String targetClassName) {
        WxCpMessage wxCpMessage = new WxCpMessage();
        wxCpMessage.setSafe("0");
        wxCpMessage.setMsgType(WxConsts.KefuMsgType.MINIPROGRAM_NOTICE);
        wxCpMessage.setAppId(wechatProperties.getEmployeeAppId());
//        wxCpMessage.setToUser(toUser);
//        wxCpMessage.setPage(String.format("pages/class/detail?id=%s", targetClassId));
//        wxCpMessage.setTitle("学生转入通知");
        wxCpMessage.setDescription(record.getCreateTime().format(FORMATTER_TIME_HHmm_CN));
        LinkedHashMap<String, String> items = new LinkedHashMap<>();
        items.put("学生", student.getName());
        items.put("联系方式", student.getParentPhone());
        items.put("调出班级", originalClassName);
        items.put("调入班级", targetClassName);
        Integer lessonIndexSize = record.getOriginalLessonIndexes().size();
        String lessonIndexStr = StrUtil.join("、", record.getOriginalLessonIndexes());
        items.put("调课课次", String.format("第%s节, 共%d节", lessonIndexStr, lessonIndexSize));
        wxCpMessage.setContentItems(items);
        wxCpMessage.setEmphasisFirstItem(true);

        return wxCpMessage;
    }

}
